﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using ERPStore.Web.Extensions;
using ERPStore.Web.Html;

using CloudSoft.Extensions;

namespace ERPStore.Coupons.Services.Providers
{
	public abstract class CouponProviderBase
	{
		public CouponProviderBase()
		{

		}

		public Models.Coupon Coupon { get; set; }
		public virtual string Name { get; set; }
		public abstract string Description { get; }

		public virtual IList<ERPStore.Models.BrokenRule> ValidateUse(ERPStore.Models.OrderCart cart, ERPStore.Models.UserPrincipal principal)
		{
			var result = new List<ERPStore.Models.BrokenRule>();
			var couponList = cart.DiscountList.Cast<Models.CartDiscount>().Select(i => i.CouponSource).Distinct(s => s.ProviderName);
			if (Coupon == null)
			{
				return null;
			}

			if (Coupon.ExpirationDate.HasValue
				&& Coupon.ExpirationDate.Value <= DateTime.Today)
			{
				result.AddBrokenRule("couponcode", string.Format("La date d'expiration ({0:dddd dd MMMM yyyy}) est atteinte pour beneficier d'une reduction", Coupon.ExpirationDate.Value));
			}

			if (Coupon.MinimumPurchase.HasValue
				&& cart.TotalWithoutDiscountByItem <= Coupon.MinimumPurchase.GetValueOrDefault(0))
			{
				result.AddBrokenRule("couponcode", string.Format("Le montant de ({0}) n'est pas atteint pour beneficier d'une reduction", Coupon.MinimumPurchase.Value.ToCurrency()));
			}


			if (Coupon.MinimumItemCount.HasValue
				&& cart.ItemCount < Coupon.MinimumItemCount)
			{
				result.AddBrokenRule("couponcode", string.Format("Le nombre de lignes n'est pas atteint ({0}) pour beneficier d'une reduction", Coupon.MinimumItemCount.Value));
			}


			if (Coupon.MaximumUseCount.HasValue
				&& Coupon.UsedCount >= Coupon.MaximumUseCount)
			{
				result.AddBrokenRule("couponcode", string.Format("Ce coupon a atteint son nombre maximal d'utilisation ({0}) pour beneficier d'une reduction.", Coupon.MaximumUseCount.Value));
			}
			var existing = cart.DiscountList.Any(i => i.Code.Equals(Coupon.Code, StringComparison.InvariantCultureIgnoreCase));

			if (existing && !Coupon.IsCumulable)
			{
				result.AddBrokenRule("couponcode", "Ce coupon n'est pas cumulable.");
			}

			if (cart.DiscountList.Count() > 0
				&& Coupon.IsExclusive)
			{
				result.AddBrokenRule("couponcode", "Ce coupon exclusif n'est pas cumulable avec d'autres coupons.");
			}

			var exclusiveExists = cart.DiscountList.Cast<Models.CartDiscount>().Any(i => i.CouponSource.IsExclusive);
			if (exclusiveExists)
			{
				result.AddBrokenRule("couponcode", "Un coupon exclusif est déjà appliqué à ce panier.");
			}

			var offeredProductCount = cart.Items.Where(i => !i.OfferName.IsNullOrEmpty()).Count();
			if (offeredProductCount == cart.Items.Count
				&& !Coupon.AllowDiscountOnOfferedProduct)
			{
				result.AddBrokenRule("couponcode", "Il n'y a pas de produits sur lequels il est possible d'appliquer ce coupon");
			}

			return result;		
		}

		public abstract void ApplyDiscountTo(Models.CartDiscount discount, ERPStore.Models.OrderCart cart, ERPStore.Models.UserPrincipal principal);
		public virtual void RemoveDiscountFrom(ERPStore.Models.OrderCart cart, ERPStore.Models.UserPrincipal principal)
		{
			// Do nothing
		}

	}
}
